package com.sunjy.common.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期工具类
 * Created by zhouyao on 2017/5/22.
 */
public class DateUtil {

	private DateUtil() {}
	
	public static final String YYYY_MM = "yyyy-MM";
	public static final String YYYY_MM_DD = "yyyy-MM-dd";
	public static final String YYYY_MM_DD_CN = "yyyy年MM月dd日";
	public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
	public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
	public static final String YYYYMMDD = "yyyyMMdd";
	public static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";

	/**
     * 获得该日期是星期几
     */
    public static Integer getDayOfWeek(Date date) {
    	if (date == null) {
    		return null;
    	}
    	Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_WEEK);
    }

	/**
	 *获取该日期的年月日 
	 */
	public static Date getYearMonthDay(Date date){
		/*Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH),0,0,0);
		return calendar.getTime();*/
		String strDate = DateFormatUtils.format(date, DateUtil.YYYY_MM_DD);
		SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.YYYY_MM_DD);
		Date returnDate = null;
		try {
			returnDate = sdf.parse(strDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return returnDate;
	}

	/**
	 *获取该日期的日
	 */
	public static int getDayByDate(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 *获取该日期的年
	 */
	public static int getYear(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.YEAR);
	}

	/**
	 *获取该日期的最后一天
	 * @param date
	 */
	public static int getLastDay(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
	}
	
	/**
	 * 获取当前日期的年月 2017-06
	 * @return
	 */
	public static String getCurrentDateYearMonth(){
		Date date = getYearMonthDay(new Date());
		String strDate = DateFormatUtils.format(date, YYYY_MM);
		return strDate;
	}

	/**
	 * 获取该日期的年月日时分秒 20170921161556
	 * @param date
	 * @return
	 */
	public static String getCurrentDateYyyyMMddHHmmss(Date date) {
		return DateFormatUtils.format(date, YYYYMMDDHHMMSS);
	}

	/**
	 * 获取当前日期的年月 2017-06
	 * @return
	 */
	public static String getCurrentDateYearMonthDay(Date date){
		return DateFormatUtils.format(date, YYYY_MM_DD);
	}

	/**
	 * 获取当前日期的年月日 2017年06月05日
	 * @return
	 */
	public static String getCurrentDateYearMonthDayCn(Date date){
		return DateFormatUtils.format(date, YYYY_MM_DD_CN);
	}


	/**
	 *	设置该日期的天
	 */
	public static Date setDateDay(Date date,int day){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), day,0,0,0);
		return calendar.getTime();
	}
	
	/**
	 * 计算两日期相差的天数
	 * 
	 * @param after
	 * @param before
	 * @return
	 */
	public static int getDateIntervalDays(Date after, Date before) {
		if (after == null || before == null) {
			throw new IllegalArgumentException("Argument after or before must be not null.");
		}
		Date afterUse = getYearMonthDay(after);
		Date beforeUse = getYearMonthDay(before);
		long intervalMilli = afterUse.getTime() - beforeUse.getTime();
		return (int) (intervalMilli / (24 * 60 * 60 * 1000));
	}

	public static int getDateIntervalMonths(Date after, Date before) {
		if (after == null || before == null) {
			throw new IllegalArgumentException("Argument after or before must be not null.");
		}
		Calendar calAfter = Calendar.getInstance();
		calAfter.setTime(after);
		Calendar calBefore = Calendar.getInstance();
		calBefore.setTime(before);
		int yearInterval = calAfter.get(Calendar.YEAR) - calBefore.get(Calendar.YEAR);
		int monthInterval = calAfter.get(Calendar.MONTH) - calBefore.get(Calendar.MONTH);
		return yearInterval * 12 + monthInterval;
	}

	public static int getDateIntervalYears(Date after, Date before) {
		if (after == null || before == null) {
			throw new IllegalArgumentException("Argument after or before must be not null.");
		}
		Calendar calAfter = Calendar.getInstance();
		calAfter.setTime(after);
		Calendar calBefore = Calendar.getInstance();
		calBefore.setTime(before);
		return calAfter.get(Calendar.YEAR) - calBefore.get(Calendar.YEAR);
	}
	
	/**
	 * 获取该日期是第几周
	 */
	public static int weekByDate(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.setTime(date);
		return calendar.get(Calendar.WEEK_OF_YEAR);
	}
	
	/**
     * 获得上月的同一天
     */
    public static Date getSameDayOfLastMonth(Date date) {
    	if (date == null) {
    		return null;
    	}
    	Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, -1);
		return new Date(calendar.getTime().getTime());
    }
	
	/**
     * 获得下月的同一天
     */
    public static Date getSameDayOfNextMonth(Date date) {
    	if (date == null) {
    		return null;
    	}
    	Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, 1);
		return new Date(calendar.getTime().getTime());
    }

	/**
	 * 根据当前的年月格式，转换成有年月中文字的格式
	 */
	public static String getNewFormatForYearMonth(String yaerMonth){
		SimpleDateFormat parser = new SimpleDateFormat(YYYY_MM);
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy年M月");
		String text = yaerMonth;
		if(StringUtils.isBlank(yaerMonth)){
			return yaerMonth;
		}else {
			try {
				text = formatter.format(parser.parse(yaerMonth));
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return text;
	}

	/**
	 * 2017年12月 格式 2017-12
	 */
	public static String getEnFormatForCnYearMonth(String yaerMonth){
		SimpleDateFormat parser = new SimpleDateFormat(YYYY_MM);
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy年M月");
		String text = yaerMonth;
		if(StringUtils.isBlank(yaerMonth)){
			return yaerMonth;
		}else {
			try {
				text = parser.format(formatter.parse(yaerMonth));
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return text;
	}

    
    /**
     * 设置该日期下一年的年,月为month
     */
    public static Date getNextYearYMonth(Date date,int month) {
    	if (date == null) {
    		return null;
    	}
    	Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.YEAR, 1);
		calendar.set(Calendar.MONTH, month-1);
		return new Date(calendar.getTime().getTime());
    }
    
    /**
     * 获得yearMonth的下一个月
     * 例如yearMonth为2017-05 返回2017-06
     * @throws ParseException 
     * @throws ParseException
     */
    public static String getSameDayOfNextMonth(String yearMonth) throws ParseException {
    	if (StringUtils.isBlank(yearMonth)) {
    		return null;
    	}
    	Date date = DateUtils.parseDate(yearMonth, YYYY_MM);
    	Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, 1);
		Date returnDate = new Date(calendar.getTime().getTime());
		String returnStrDate = DateFormatUtils.format(returnDate, YYYY_MM);
		return returnStrDate;
    }

	/**
	 * 获得yearMonth的下一个月
	 * 例如yearMonth为2017-05 返回2017-06
	 * @throws ParseException
	 * @throws ParseException
	 */
	public static String getSameDayOfNextYmd(String ymd) throws ParseException {
		if (StringUtils.isBlank(ymd)) {
			return null;
		}
		Date date = DateUtils.parseDate(ymd, YYYY_MM_DD);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, 1);
		Date returnDate = new Date(calendar.getTime().getTime());
		String returnStrDate = DateFormatUtils.format(returnDate, YYYY_MM_DD);
		return returnStrDate;
	}

	/**
     * 获得yearMonth的上一个月
     * 例如yearMonth为2017-05 返回2017-04
     * @throws ParseException 
     * @throws ParseException
     */
    public static String getSameDayOfLastMonth(String yearMonth) throws ParseException {
    	if (StringUtils.isBlank(yearMonth)) {
    		return null;
    	}
    	Date date = DateUtils.parseDate(yearMonth, YYYY_MM);
    	Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, -1);
		Date returnDate = new Date(calendar.getTime().getTime());
		String returnStrDate = DateFormatUtils.format(returnDate, YYYY_MM);
		return returnStrDate;
    }

	/**
	 * 获得yearMonth的上 howMany 个月
	 * 例如yearMonth为2017-05 返回2017-03
	 * @throws ParseException
	 * @throws ParseException
	 */
	public static String getSameDayOfLastMonth(String yearMonth, int howMany) throws ParseException {
		if (StringUtils.isBlank(yearMonth)) {
			return null;
		}
		Date date = DateUtils.parseDate(yearMonth, YYYY_MM);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, howMany);
		Date returnDate = new Date(calendar.getTime().getTime());
		String returnStrDate = DateFormatUtils.format(returnDate, YYYY_MM);
		return returnStrDate;
	}

	public static String getFeedbackDate(String yearMonth ,int feedbackDayType,int feedbackDay) throws ParseException {
		if (StringUtils.isBlank(yearMonth)) {
			return null;
		}

		String day = feedbackDay+"";
		if(feedbackDay<10){
			day = "0"+feedbackDay;
		}
		String returnStrDate = yearMonth+"-"+day;

		//获取返回的年月
		Date date = DateUtils.parseDate(yearMonth, YYYY_MM);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		if(feedbackDayType>1) {
			calendar.add(Calendar.MONTH, feedbackDayType-1);
		}
		Date returnDate = new Date(calendar.getTime().getTime());

		//根据返回的年月获取该月最后一天
		int maxDay = getLastDay(returnDate);
		if(maxDay<feedbackDay){
			feedbackDay = maxDay;
		}
		String feedDay = feedbackDay+"";
		if(feedbackDay<10){
			feedDay = "0"+feedbackDay;
		}
		returnStrDate = DateFormatUtils.format(returnDate, YYYY_MM)+"-"+feedDay;

		return returnStrDate;
	}

	/**
	 * 获取当前日期前一周
	 */
	public static Date getBeforeWeekByDate(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, -7);
		return new Date(calendar.getTime().getTime());
	}
	/**
	 * 获取当前日期后一周
	 */
	public static Date getAfterWeekByDate(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, 7);
		return new Date(calendar.getTime().getTime());
	}
	/**
	 * 获取当前日期前一tianya
	 */
	public static Date getBeforeDayByDate(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_YEAR, -1);
		return new Date(calendar.getTime().getTime());
	}


	/**
	 * 获取当前日期前一周
	 */
	public static String DateToString(Date date) {
		if (date == null) {
			return null;
		}
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
		return sdf.format(date);
	}

	/**
	 * 根据传过来的格式，把日期转为字符串
	 */
	public static String DateTimeToString(Date date,String format) {
		if (date == null) {
			return null;
		}
		if(StringUtils.isBlank(format)){
			format = "yyyy-MM-dd";
		}
		SimpleDateFormat sdf=new SimpleDateFormat(format);
		return sdf.format(date);
	}

	/**
	 * 根据传过来的格式，把日期转为字符串
	 */
	public static Date DateTimeToString(String date,String format) {
		if (StringUtils.isBlank(date)) {
			return null;
		}
		if(StringUtils.isBlank(format)){
			format = "yyyy-MM-dd";
		}
		SimpleDateFormat sdf=new SimpleDateFormat(format);
		Date newDate = null;
		try {
			newDate= sdf.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return newDate;
	}

	/**
	 * 获取当前日期的年月 2017-06
	 * @return
	 */
	public static String getCurrentDateYearMonth(Date date){
		String strDate = DateFormatUtils.format(date, YYYY_MM);
		return strDate;
	}

	/**
	 * 获取当前时间2017-08-07
	 * @return
	 */
	public static String getDateToMmSs(Date date){
		return DateFormatUtils.format(date, YYYY_MM_DD);
	}

	/**
	 * 获取该日期的年月日 20181121
	 * @param date
	 * @return
	 */
	public static String getYmd(Date date){
		String format = DateFormatUtils.format(date, YYYYMMDD);
		return format;
	}


	/**
	 * 获取当前日期的前一天
	 * @return
	 */
	public static String getSpecifiedDayBefore(String specifiedDay) {
		Calendar c = Calendar.getInstance();
		Date date = null;
		try {
			date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.setTime(date);
		int day = c.get(Calendar.DATE);
		c.set(Calendar.DATE, day - 1);

		String dayBefore = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
		return dayBefore;
	}

	public static Date returnCurrentDatePlusHowManyDay(int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DAY_OF_MONTH, day);
		return new Date(calendar.getTime().getTime());
	}

	public static Date returnDatePlusHowManyDay(Date date, int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, day);
		return new Date(calendar.getTime().getTime());
	}

	public static Date returnCurrentDatePlusHowManyMonth(int month) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.MONTH, month);
		return new Date(calendar.getTime().getTime());
	}

	public static void main(String[] args) throws ParseException {
		String enFormatForCnYearMonth = getEnFormatForCnYearMonth("2017年12月");
		System.out.println("enFormatForCnYearMonth+++++" + enFormatForCnYearMonth);
		String str = "2017-03-31";
		Date d2 = DateUtils.parseDate(str, "yyyy-MM-dd");
		Date nextMonthDate = DateUtil.getSameDayOfNextMonth(d2);
		String s = DateFormatUtils.format(nextMonthDate,DateUtil.YYYY_MM_DD);
		System.out.println("+++++" + s);
		System.out.println("===="+getSameDayOfLastMonth("2017-10",-2));
		System.out.println("-----" + getBeforeDayByDate(new Date()));
		System.out.println("getSameDayOfNextYmd-----" + getSameDayOfNextYmd("2018-05-31"));

		Date startDate = DateUtils.parseDate("2018-06-02", DateUtil.YYYY_MM_DD);
		Date endDate = DateUtils.parseDate("2018-06-02", DateUtil.YYYY_MM_DD);
		int dateIntervalDays = getDateIntervalDays(endDate, startDate);
		System.out.println("dateIntervalDays===" + dateIntervalDays);
		List<String> strings = listTowStrDateBetweenData("2018-05-03", "2018-05-03");
		System.out.println("strings:" + strings);
		System.out.println("returnDatePlusHowManyDay==="+ DateFormatUtils.format(returnDatePlusHowManyDay(new Date(),1),DateUtil.YYYY_MM_DD));
		System.out.println("getYmdIsDay===" + getYmdIsDay("2018-08-22"));
		System.out.println("getYear===" + getYear(new Date()));
	}
    
    public static boolean isValidDate(String fomat,String s)
    {
    	SimpleDateFormat dateFormat =  new SimpleDateFormat(fomat);
		dateFormat.setLenient(false);
        try
        {
             dateFormat.parse(s);
             return true;
         }
        catch (Exception e)
        {
            // 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
            return false;
        }
    }

	/**
	 * 获取当前日期的前一天日期
	 * @param date
	 * @return
     */
	public static Date getNextDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		date = calendar.getTime();
		return date;
	}

	public static Boolean checkPayMonth(String startMonth, String endMonth, String payMonth){
		try{
			if(StringUtils.isBlank(startMonth)){
				return false;
			}
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
			Date endMonthDate = null;
			Date payMonthDate = format.parse( payMonth);
			Date startMonthDate = format.parse(startMonth);
			if(endMonth != null && !"".equals(endMonth)){
				Date endDate = format.parse(endMonth);
				endMonthDate = endDate;
			}
			if(endMonthDate != null){
				if(payMonthDate.compareTo(startMonthDate) != -1 && payMonthDate.compareTo(endMonthDate) != 1){
					return true;
				}
			} else {
				if(payMonthDate.compareTo(startMonthDate) != -1){
					return true;
				}
			}
		}catch (ParseException e) {
			e.printStackTrace();
			return false;
		}
		return false;
	}

	/**
	 * 获取month的月 2018-05 5
	 * @return
	 */
	public static String getYearMonthIsMonth(String yearMonth){
		if (StringUtils.isBlank(yearMonth)) {
			return "";
		}
		String substring = yearMonth.substring(5);
		if (substring.startsWith("0")) {
			return substring.substring(1);
		}
		return substring;
	}

	public static List<String> listTowStrDateBetweenData(String start, String end) throws ParseException {
		List<String> list = new ArrayList<>();
		list.add(start);
		Date startDate = DateUtils.parseDate(start, DateUtil.YYYY_MM_DD);
		Date endDate = DateUtils.parseDate(end, DateUtil.YYYY_MM_DD);
		int dateIntervalDays = getDateIntervalDays(endDate, startDate) + 1;
		if (dateIntervalDays == 1) {
			return list;
		} else {
			String nextStart = start;
			for (int i = 1; i < dateIntervalDays; i++) {
				nextStart = getSameDayOfNextYmd(nextStart);
				list.add(nextStart);
			}
		}
		return list;
	}

	/**
	 * 获取当前日期后一天
	 */
	public static Date getAfterDayByDate(Date date) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_YEAR, 1);
		return new Date(calendar.getTime().getTime());
	}


	/**
	 * 获取当前日期后n天
	 */
	public static Date getAfterDayByDay(Date date, int day) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_YEAR, day);
		return new Date(calendar.getTime().getTime());
	}

	public static String getYmdIsDay(String ymd) {
		if (StringUtils.isBlank(ymd)) {
			return "";
		}
		return ymd.substring(8);
	}

	public static String getYmdIsYm(String ymd) {
		if (StringUtils.isBlank(ymd)) {
			return "";
		}
		return ymd.substring(0,7);
	}

	public static String getCNYearMonth(String yearMonth) {
		if (StringUtils.isBlank(yearMonth)) {
			return "";
		}
		return yearMonth.replace("-","年") + "月";
	}

	/**
	 * 判断日期是否在之间，在返回true
	 * @param currentDate
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static Boolean compareDateRange(Date currentDate,Date startDate,Date endDate) {
		int i = currentDate.compareTo(startDate);
		int j = currentDate.compareTo(endDate);
		if ((i == 0 || i == 1) && (j == 0 || j == -1)) {
			return true;
		}
		return false;
	}

}
